(function () {
    /**
     * Converts a colon formatted string to a object with properties.
     *
     * This is process a provided string and look for any tokens in the format
     * of `:name[=value]` and then convert it to a object and return.
     * An example of this is ':include :type=code :fragment=demo' is taken and
     * then converted to:
     *
     * ```
     * {
     *  include: '',
     *  type: 'code',
     *  fragment: 'demo'
     * }
     * ```
     *
     * @param {string}   str   The string to parse.
     *
     * @return {object}  The original string and parsed object, { str, config }.
     */
    function getAndRemoveConfig(str) {
      if ( str === void 0 ) str = '';
  
      var config = {};
  
      if (str) {
        str = str
          .replace(/^('|")/, '')
          .replace(/('|")$/, '')
          .replace(/(?:^|\s):([\w-]+:?)=?([\w-%]+)?/g, function (m, key, value) {
            if (key.indexOf(':') === -1) {
              config[key] = (value && value.replace(/&quot;/g, '')) || true;
              return '';
            }
  
            return m;
          })
          .trim();
      }
  
      return { str: str, config: config };
    }
  
    function removeDocsifyIgnoreTag(str) {
      return str
        .replace(/<!-- {docsify-ignore} -->/, '')
        .replace(/{docsify-ignore}/, '')
        .replace(/<!-- {docsify-ignore-all} -->/, '')
        .replace(/{docsify-ignore-all}/, '')
        .trim();
    }
  
    /* eslint-disable no-unused-vars */
  
    var INDEXS = {};
  
    var LOCAL_STORAGE = {
      EXPIRE_KEY: 'docsify.search.expires',
      INDEX_KEY: 'docsify.search.index',
    };
  
    function resolveExpireKey(namespace) {
      return namespace
        ? ((LOCAL_STORAGE.EXPIRE_KEY) + "/" + namespace)
        : LOCAL_STORAGE.EXPIRE_KEY;
    }
  
    function resolveIndexKey(namespace) {
      return namespace
        ? ((LOCAL_STORAGE.INDEX_KEY) + "/" + namespace)
        : LOCAL_STORAGE.INDEX_KEY;
    }
  
    function escapeHtml(string) {
      var entityMap = {
        '&': '&amp;',
        '<': '&lt;',
        '>': '&gt;',
        '"': '&quot;',
        "'": '&#39;',
      };
  
      return String(string).replace(/[&<>"']/g, function (s) { return entityMap[s]; });
    }
  
    function getAllPaths(router) {
      var paths = [];
  
      Docsify.dom
        .findAll('.sidebar-nav a:not(.section-link):not([data-nosearch])')
        .forEach(function (node) {
          var href = node.href;
          var originHref = node.getAttribute('href');
          var path = router.parse(href).path;
  
          if (
            path &&
            paths.indexOf(path) === -1 &&
            !Docsify.util.isAbsolutePath(originHref)
          ) {
            paths.push(path);
          }
        });
  
      return paths;
    }
  
    function getTableData(token) {
      if (!token.text && token.type === 'table') {
        token.rows.unshift(token.header);
        token.text = token.rows
          .map(function (columns) { return columns.map(function (r) { return r.text; }).join(' | '); })
          .join(' |\n ');
      }
      return token.text;
    }
  
    function getListData(token) {
      if (!token.text && token.type === 'list') {
        token.text = token.raw;
      }
      return token.text;
    }
  
    function saveData(maxAge, expireKey, indexKey) {
      localStorage.setItem(expireKey, Date.now() + maxAge);
      localStorage.setItem(indexKey, JSON.stringify(INDEXS));
    }
  
    function genIndex(path, content, router, depth) {
      if ( content === void 0 ) content = '';
  
      var tokens = window.marked.lexer(content);
      var slugify = window.Docsify.slugify;
      var index = {};
      var slug;
      var title = '';
  
      tokens.forEach(function (token, tokenIndex) {
        if (token.type === 'heading' && token.depth <= depth) {
          var ref = getAndRemoveConfig(token.text);
          var str = ref.str;
          var config = ref.config;
  
          var text = removeDocsifyIgnoreTag(token.text);
  
          if (config.id) {
            slug = router.toURL(path, { id: slugify(config.id) });
          } else {
            slug = router.toURL(path, { id: slugify(escapeHtml(text)) });
          }
  
          if (str) {
            title = removeDocsifyIgnoreTag(str);
          }
  
          index[slug] = { slug: slug, title: title, body: '' };
        } else {
          if (tokenIndex === 0) {
            slug = router.toURL(path);
            index[slug] = {
              slug: slug,
              title: path !== '/' ? path.slice(1) : 'Home Page',
              body: token.text || '',
            };
          }
  
          if (!slug) {
            return;
          }
  
          if (!index[slug]) {
            index[slug] = { slug: slug, title: '', body: '' };
          } else if (index[slug].body) {
            token.text = getTableData(token);
            token.text = getListData(token);
  
            index[slug].body += '\n' + (token.text || '');
          } else {
            token.text = getTableData(token);
            token.text = getListData(token);
  
            index[slug].body = token.text || '';
          }
        }
      });
      slugify.clear();
      return index;
    }
  
    function ignoreDiacriticalMarks(keyword) {
      if (keyword && keyword.normalize) {
        return keyword.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
      }
      return keyword;
    }
  
    /**
     * @param {String} query Search query
     * @returns {Array} Array of results
     */
    function search(query) {
      var matchingResults = [];
      var data = [];
      Object.keys(INDEXS).forEach(function (key) {
        data = data.concat(Object.keys(INDEXS[key]).map(function (page) { return INDEXS[key][page]; }));
      });
  
      query = query.trim();
      var keywords = query.split(/[\s\-，\\/]+/);
      if (keywords.length !== 1) {
        keywords = [].concat(query, keywords);
      }
  
      var loop = function ( i ) {
        var post = data[i];
        var matchesScore = 0;
        var resultStr = '';
        var handlePostTitle = '';
        var handlePostContent = '';
        var postTitle = post.title && post.title.trim();
        var postContent = post.body && post.body.trim();
        var postUrl = post.slug || '';
  
        if (postTitle) {
          keywords.forEach(function (keyword) {
            // From https://github.com/sindresorhus/escape-string-regexp
            var regEx = new RegExp(
              escapeHtml(ignoreDiacriticalMarks(keyword)).replace(
                /[|\\{}()[\]^$+*?.]/g,
                '\\$&'
              ),
              'gi'
            );
            var indexTitle = -1;
            var indexContent = -1;
            handlePostTitle = postTitle
              ? escapeHtml(ignoreDiacriticalMarks(postTitle))
              : postTitle;
            handlePostContent = postContent
              ? escapeHtml(ignoreDiacriticalMarks(postContent))
              : postContent;
  
            indexTitle = postTitle ? handlePostTitle.search(regEx) : -1;
            indexContent = postContent ? handlePostContent.search(regEx) : -1;
  
            if (indexTitle >= 0 || indexContent >= 0) {
              matchesScore += indexTitle >= 0 ? 3 : indexContent >= 0 ? 2 : 0;
              if (indexContent < 0) {
                indexContent = 0;
              }
  
              var start = 0;
              var end = 0;
  
              start = indexContent < 11 ? 0 : indexContent - 10;
              end = start === 0 ? 70 : indexContent + keyword.length + 60;
  
              if (postContent && end > postContent.length) {
                end = postContent.length;
              }
  
              var matchContent =
                handlePostContent &&
                '...' +
                  handlePostContent
                    .substring(start, end)
                    .replace(
                      regEx,
                      function (word) { return ("<em class=\"search-keyword\">" + word + "</em>"); }
                    ) +
                  '...';
  
              resultStr += matchContent;
            }
          });
  
          if (matchesScore > 0) {
            var matchingPost = {
              title: handlePostTitle,
              content: postContent ? resultStr : '',
              url: postUrl,
              score: matchesScore,
            };
  
            matchingResults.push(matchingPost);
          }
        }
      };
  
      for (var i = 0; i < data.length; i++) loop( i );
  
      return matchingResults.sort(function (r1, r2) { return r2.score - r1.score; });
    }
  
    function init(config, vm) {
      var isAuto = config.paths === 'auto';
      var paths = isAuto ? getAllPaths(vm.router) : config.paths;
  
      var namespaceSuffix = '';
  
      // only in auto mode
      if (paths.length && isAuto && config.pathNamespaces) {
        var path = paths[0];
  
        if (Array.isArray(config.pathNamespaces)) {
          namespaceSuffix =
            config.pathNamespaces.filter(
              function (prefix) { return path.slice(0, prefix.length) === prefix; }
            )[0] || namespaceSuffix;
        } else if (config.pathNamespaces instanceof RegExp) {
          var matches = path.match(config.pathNamespaces);
  
          if (matches) {
            namespaceSuffix = matches[0];
          }
        }
        var isExistHome = paths.indexOf(namespaceSuffix + '/') === -1;
        var isExistReadme = paths.indexOf(namespaceSuffix + '/README') === -1;
        if (isExistHome && isExistReadme) {
          paths.unshift(namespaceSuffix + '/');
        }
      } else if (paths.indexOf('/') === -1 && paths.indexOf('/README') === -1) {
        paths.unshift('/');
      }
  
      var expireKey = resolveExpireKey(config.namespace) + namespaceSuffix;
      var indexKey = resolveIndexKey(config.namespace) + namespaceSuffix;
  
      var isExpired = localStorage.getItem(expireKey) < Date.now();
  
      INDEXS = JSON.parse(localStorage.getItem(indexKey));
  
      if (isExpired) {
        INDEXS = {};
      } else if (!isAuto) {
        return;
      }
  
      var len = paths.length;
      var count = 0;
  
      paths.forEach(function (path) {
        if (INDEXS[path]) {
          return count++;
        }
  
        Docsify.get(vm.router.getFile(path), false, vm.config.requestHeaders).then(
          function (result) {
            INDEXS[path] = genIndex(path, result, vm.router, config.depth);
            len === ++count && saveData(config.maxAge, expireKey, indexKey);
          }
        );
      });
    }
  
    /* eslint-disable no-unused-vars */
  
    var NO_DATA_TEXT = '';
    var options;
  
    function style() {
      var code = "\n.sidebar {\n  padding-top: 0;\n}\n\n.search {\n  margin-bottom: 20px;\n  padding: 6px;\n  border-bottom: 1px solid #eee;\n}\n\n.search .input-wrap {\n  display: flex;\n  align-items: center;\n}\n\n.search .results-panel {\n  display: none;\n}\n\n.search .results-panel.show {\n  display: block;\n}\n\n.search input {\n  outline: none;\n  border: none;\n  width: 100%;\n  padding: 0.6em 7px;\n  font-size: inherit;\n  border: 1px solid transparent;\n}\n\n.search input:focus {\n  box-shadow: 0 0 5px var(--theme-color, #42b983);\n  border: 1px solid var(--theme-color, #42b983);\n}\n\n.search input::-webkit-search-decoration,\n.search input::-webkit-search-cancel-button,\n.search input {\n  -webkit-appearance: none;\n  -moz-appearance: none;\n  appearance: none;\n}\n\n.search input::-ms-clear {\n  display: none;\n  height: 0;\n  width: 0;\n}\n\n.search .clear-button {\n  cursor: pointer;\n  width: 36px;\n  text-align: right;\n  display: none;\n}\n\n.search .clear-button.show {\n  display: block;\n}\n\n.search .clear-button svg {\n  transform: scale(.5);\n}\n\n.search h2 {\n  font-size: 17px;\n  margin: 10px 0;\n}\n\n.search a {\n  text-decoration: none;\n  color: inherit;\n}\n\n.search .matching-post {\n  border-bottom: 1px solid #eee;\n}\n\n.search .matching-post:last-child {\n  border-bottom: 0;\n}\n\n.search p {\n  font-size: 14px;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  display: -webkit-box;\n  -webkit-line-clamp: 2;\n  -webkit-box-orient: vertical;\n}\n\n.search p.empty {\n  text-align: center;\n}\n\n.app-name.hide, .sidebar-nav.hide {\n  display: none;\n}";
  
      Docsify.dom.style(code);
    }
  
    function tpl(defaultValue) {
      if ( defaultValue === void 0 ) defaultValue = '';
  
      var html = "<div class=\"input-wrap\">\n      <input type=\"search\" value=\"" + defaultValue + "\" aria-label=\"Search text\" />\n      <div class=\"clear-button\">\n        <svg width=\"26\" height=\"24\">\n          <circle cx=\"12\" cy=\"12\" r=\"11\" fill=\"#ccc\" />\n          <path stroke=\"white\" stroke-width=\"2\" d=\"M8.25,8.25,15.75,15.75\" />\n          <path stroke=\"white\" stroke-width=\"2\"d=\"M8.25,15.75,15.75,8.25\" />\n        </svg>\n      </div>\n    </div>\n    <div class=\"results-panel\"></div>\n    </div>";
      var el = Docsify.dom.create('div', html);
      var aside = Docsify.dom.find('aside');
  
      Docsify.dom.toggleClass(el, 'search');
      Docsify.dom.before(aside, el);
    }
  
    function doSearch(value) {
      var $search = Docsify.dom.find('div.search');
      var $panel = Docsify.dom.find($search, '.results-panel');
      var $clearBtn = Docsify.dom.find($search, '.clear-button');
      var $sidebarNav = Docsify.dom.find('.sidebar-nav');
      var $appName = Docsify.dom.find('.app-name');
  
      if (!value) {
        $panel.classList.remove('show');
        $clearBtn.classList.remove('show');
        $panel.innerHTML = '';
  
        if (options.hideOtherSidebarContent) {
          $sidebarNav && $sidebarNav.classList.remove('hide');
          $appName && $appName.classList.remove('hide');
        }
  
        return;
      }
  
      var matchs = search(value);
  
      var html = '';
      matchs.forEach(function (post) {
        html += "<div class=\"matching-post\">\n<a href=\"" + (post.url) + "\">\n<h2>" + (post.title) + "</h2>\n<p>" + (post.content) + "</p>\n</a>\n</div>";
      });
  
      $panel.classList.add('show');
      $clearBtn.classList.add('show');
      $panel.innerHTML = html || ("<p class=\"empty\">" + NO_DATA_TEXT + "</p>");
      if (options.hideOtherSidebarContent) {
        $sidebarNav && $sidebarNav.classList.add('hide');
        $appName && $appName.classList.add('hide');
      }
    }
  
    function bindEvents() {
      var $search = Docsify.dom.find('div.search');
      var $input = Docsify.dom.find($search, 'input');
      var $inputWrap = Docsify.dom.find($search, '.input-wrap');
  
      var timeId;
  
      /**
        Prevent to Fold sidebar.
  
        When searching on the mobile end,
        the sidebar is collapsed when you click the INPUT box,
        making it impossible to search.
       */
      Docsify.dom.on(
        $search,
        'click',
        function (e) { return ['A', 'H2', 'P', 'EM'].indexOf(e.target.tagName) === -1 &&
          e.stopPropagation(); }
      );
      Docsify.dom.on($input, 'input', function (e) {
        clearTimeout(timeId);
        timeId = setTimeout(function (_) { return doSearch(e.target.value.trim()); }, 100);
      });
      Docsify.dom.on($inputWrap, 'click', function (e) {
        // Click input outside
        if (e.target.tagName !== 'INPUT') {
          $input.value = '';
          doSearch();
        }
      });
    }
  
    function updatePlaceholder(text, path) {
      var $input = Docsify.dom.getNode('.search input[type="search"]');
  
      if (!$input) {
        return;
      }
  
      if (typeof text === 'string') {
        $input.placeholder = text;
      } else {
        var match = Object.keys(text).filter(function (key) { return path.indexOf(key) > -1; })[0];
        $input.placeholder = text[match];
      }
    }
  
    function updateNoData(text, path) {
      if (typeof text === 'string') {
        NO_DATA_TEXT = text;
      } else {
        var match = Object.keys(text).filter(function (key) { return path.indexOf(key) > -1; })[0];
        NO_DATA_TEXT = text[match];
      }
    }
  
    function updateOptions(opts) {
      options = opts;
    }
  
    function init$1(opts, vm) {
      var keywords = vm.router.parse().query.s;
  
      updateOptions(opts);
      style();
      tpl(keywords);
      bindEvents();
      keywords && setTimeout(function (_) { return doSearch(keywords); }, 500);
    }
  
    function update(opts, vm) {
      updateOptions(opts);
      updatePlaceholder(opts.placeholder, vm.route.path);
      updateNoData(opts.noData, vm.route.path);
    }
  
    /* eslint-disable no-unused-vars */
  
    var CONFIG = {
      placeholder: 'Type to search',
      noData: 'No Results!',
      paths: 'auto',
      depth: 2,
      maxAge: 86400000, // 1 day
      hideOtherSidebarContent: false,
      namespace: undefined,
      pathNamespaces: undefined,
    };
  
    var install = function (hook, vm) {
      var util = Docsify.util;
      var opts = vm.config.search || CONFIG;
  
      if (Array.isArray(opts)) {
        CONFIG.paths = opts;
      } else if (typeof opts === 'object') {
        CONFIG.paths = Array.isArray(opts.paths) ? opts.paths : 'auto';
        CONFIG.maxAge = util.isPrimitive(opts.maxAge) ? opts.maxAge : CONFIG.maxAge;
        CONFIG.placeholder = opts.placeholder || CONFIG.placeholder;
        CONFIG.noData = opts.noData || CONFIG.noData;
        CONFIG.depth = opts.depth || CONFIG.depth;
        CONFIG.hideOtherSidebarContent =
          opts.hideOtherSidebarContent || CONFIG.hideOtherSidebarContent;
        CONFIG.namespace = opts.namespace || CONFIG.namespace;
        CONFIG.pathNamespaces = opts.pathNamespaces || CONFIG.pathNamespaces;
      }
  
      var isAuto = CONFIG.paths === 'auto';
  
      hook.mounted(function (_) {
        init$1(CONFIG, vm);
        !isAuto && init(CONFIG, vm);
      });
      hook.doneEach(function (_) {
        update(CONFIG, vm);
        isAuto && init(CONFIG, vm);
      });
    };
  
    $docsify.plugins = [].concat(install, $docsify.plugins);
  
  }());
  